/**
 * @file pipeline.cpp
 * @brief 配置流水线与插件机制的实现文件。
 * @details 提供 `cfg::PluginRegistry`、`cfg::PipelineRunner` 以及
 *          `cfg::plugin::PluginOptionsChecker` 的函数实现，并承担运行时调度。
 */
#include "pipeline.h"

#include <algorithm>
#include <cctype>
#include <iterator>

namespace cfg
{

/// PluginRegistry 实现
/**
 * @brief 返回插件注册表单例。线程安全初始化。
 * @return `PluginRegistry` 单例引用。
 */
PluginRegistry &
PluginRegistry::instance()
{
    static PluginRegistry inst;
    return inst;
}

/**
 * @brief 注册一个源提供者工厂。
 * @param name 插件名称键。
 * @param factory 工厂函数对象。
 */
void
PluginRegistry::register_provider(const std::string & name, ProviderFactory factory)
{
    _providers[name] = std::move(factory);
}

/**
 * @brief 注册一个变换器工厂。
 * @param name 插件名称键。
 * @param factory 工厂函数对象。
 */
void
PluginRegistry::register_transformer(const std::string & name, TransformerFactory factory)
{
    _transformers[name] = std::move(factory);
}

/**
 * @brief 注册一个校验器工厂。
 * @param name 插件名称键。
 * @param factory 工厂函数对象。
 */
void
PluginRegistry::register_validator(const std::string & name, ValidatorFactory factory)
{
    _validators[name] = std::move(factory);
}

/**
 * @brief 注册一个 sink 工厂。
 * @param name 插件名称键。
 * @param factory 工厂函数对象。
 */
void
PluginRegistry::register_sink(const std::string & name, SinkFactory factory)
{
    _sinks[name] = std::move(factory);
}

/**
 * @brief 创建已注册的 provider 实例。
 * @param name 插件名称。
 * @return 智能指针；未找到返回 `nullptr`。
 */
std::unique_ptr<IProvider>
PluginRegistry::create_provider(const std::string & name) const
{
    auto it = _providers.find(name);
    if (it == _providers.end())
        return nullptr;
    return it->second();
}

/**
 * @brief 创建已注册的 transformer 实例。
 * @param name 插件名称。
 * @return 智能指针；未找到返回 `nullptr`。
 */
std::unique_ptr<ITransformer>
PluginRegistry::create_transformer(const std::string & name) const
{
    auto it = _transformers.find(name);
    if (it == _transformers.end())
        return nullptr;
    return it->second();
}

/**
 * @brief 创建已注册的 validator 实例。
 * @param name 插件名称。
 * @return 智能指针；未找到返回 `nullptr`。
 */
std::unique_ptr<IValidator>
PluginRegistry::create_validator(const std::string & name) const
{
    auto it = _validators.find(name);
    if (it == _validators.end())
        return nullptr;
    return it->second();
}

/**
 * @brief 创建已注册的 sink 实例。
 * @param name 插件名称。
 * @return 智能指针；未找到返回 `nullptr`。
 */
std::unique_ptr<ISink>
PluginRegistry::create_sink(const std::string & name) const
{
    auto it = _sinks.find(name);
    if (it == _sinks.end())
        return nullptr;
    return it->second();
}

/**
 * @brief 列出已注册的 provider 名称。
 * @return 名称列表，按字典序排序返回。
 */
std::vector<std::string>
PluginRegistry::list_providers() const
{
    std::vector<std::string> names;
    names.reserve(_providers.size());
    for (const auto & kv : _providers)
        names.push_back(kv.first);
    std::sort(names.begin(), names.end());
    return names;
}

/**
 * @brief 列出已注册的 transformer 名称。
 * @return 名称列表，按字典序排序返回。
 */
std::vector<std::string>
PluginRegistry::list_transformers() const
{
    std::vector<std::string> names;
    names.reserve(_transformers.size());
    for (const auto & kv : _transformers)
        names.push_back(kv.first);
    std::sort(names.begin(), names.end());
    return names;
}

/**
 * @brief 列出已注册的 validator 名称。
 * @return 名称列表，按字典序排序返回。
 */
std::vector<std::string>
PluginRegistry::list_validators() const
{
    std::vector<std::string> names;
    names.reserve(_validators.size());
    for (const auto & kv : _validators)
        names.push_back(kv.first);
    std::sort(names.begin(), names.end());
    return names;
}

/**
 * @brief 列出已注册的 sink 名称。
 * @return 名称列表，按字典序排序返回。
 */
std::vector<std::string>
PluginRegistry::list_sinks() const
{
    std::vector<std::string> names;
    names.reserve(_sinks.size());
    for (const auto & kv : _sinks)
        names.push_back(kv.first);
    std::sort(names.begin(), names.end());
    return names;
}

/**
 * @brief 判断指定类别与名称的插件是否存在。
 * @param category 插件类别：`"provider"|"transformer"|"validator"|"sink"`。
 * @param name 插件名称。
 * @return 存在返回 true，否则返回 false。
 */
bool
PluginRegistry::exists(const std::string & category, const std::string & name) const
{
    if (category == "provider")
        return _providers.find(name) != _providers.end();
    if (category == "transformer")
        return _transformers.find(name) != _transformers.end();
    if (category == "validator")
        return _validators.find(name) != _validators.end();
    if (category == "sink")
        return _sinks.find(name) != _sinks.end();
    return false;
}

/// AttachmentRegistry 实现
AttachmentRegistry &
AttachmentRegistry::instance()
{
    static AttachmentRegistry inst;
    return inst;
}

void
AttachmentRegistry::attach_transformer(TransformerSpec spec, int priority)
{
    std::lock_guard<std::mutex> lk(_mtx);
    TransformerAttach t{std::move(spec), priority, _seq_counter++};
    _t.push_back(std::move(t));
}

void
AttachmentRegistry::attach_validator(ValidatorSpec spec, int priority)
{
    std::lock_guard<std::mutex> lk(_mtx);
    ValidatorAttach v{std::move(spec), priority, _seq_counter++};
    _v.push_back(std::move(v));
}

std::vector<TransformerSpec>
AttachmentRegistry::collect_transformers() const
{
    std::lock_guard<std::mutex> lk(_mtx);
    std::vector<TransformerAttach> list = _t; // 拷贝后排序，保持稳定
    std::sort(list.begin(),
              list.end(),
              [](const TransformerAttach & a, const TransformerAttach & b)
              {
                  if (a.priority != b.priority)
                      return a.priority < b.priority;
                  return a.seq < b.seq;
              });
    std::vector<TransformerSpec> out;
    out.reserve(list.size());
    for (auto & t : list)
        out.push_back(t.spec);
    return out;
}

std::vector<ValidatorSpec>
AttachmentRegistry::collect_validators() const
{
    std::lock_guard<std::mutex> lk(_mtx);
    std::vector<ValidatorAttach> list = _v; // 拷贝后排序，保持稳定
    std::sort(list.begin(),
              list.end(),
              [](const ValidatorAttach & a, const ValidatorAttach & b)
              {
                  if (a.priority != b.priority)
                      return a.priority < b.priority;
                  return a.seq < b.seq;
              });
    std::vector<ValidatorSpec> out;
    out.reserve(list.size());
    for (auto & v : list)
        out.push_back(v.spec);
    return out;
}

/// PipelineRunner 实现
/**
 * @brief 按给定规范执行配置流水线。
 * @param spec 流水线规范，包含 providers / transformers / validators / sinks。
 * @return 运行结果，包含根配置与收集的错误。
 */
PipelineResult
PipelineRunner::run(const PipelineSpec & spec) const
{
    PipelineResult result;
    std::vector<ConfigError> stage_errors;

    Builder builder;

    // providers 阶段
    for (const auto & p : spec.providers)
    {
        auto prov = PluginRegistry::instance().create_provider(p.name);
        if (!prov)
        {
            result.errors.emplace_back(
                ConfigError{Errc::Other, std::string("unknown provider: ") + p.name, {}});
            continue;
        }
        bool ok = prov->provide(builder, p.options, stage_errors);
        // 无论返回值如何，合并并清空阶段错误，确保非致命告警不丢失且不跨插件污染。
        if (!stage_errors.empty())
        {
            std::move(stage_errors.begin(), stage_errors.end(), std::back_inserter(result.errors));
            stage_errors.clear();
        }
        (void)ok; // 保留返回值以后续可能用途，目前不改变流程控制。
    }

    // transformers 阶段
    for (const auto & t : spec.transformers)
    {
        auto tr = PluginRegistry::instance().create_transformer(t.name);
        if (!tr)
        {
            result.errors.emplace_back(
                ConfigError{Errc::Other, std::string("unknown transformer: ") + t.name, {}});
            continue;
        }
        bool ok = tr->transform(builder, t.options, stage_errors);
        // 无论返回值如何，合并并清空阶段错误，确保非致命告警不丢失且不跨插件污染。
        if (!stage_errors.empty())
        {
            std::move(stage_errors.begin(), stage_errors.end(), std::back_inserter(result.errors));
            stage_errors.clear();
        }
        (void)ok;
    }

    // freeze
    auto frozen = builder.freeze();
    if (!frozen)
    {
        // 将构建期错误全部导入（ranges 方式复制）
        std::copy(frozen.error().begin(), frozen.error().end(), std::back_inserter(result.errors));
        return result; // validators 跳过
    }

    result.root = *frozen;
    View root_view(result.root);

    // validators 阶段
    for (const auto & v : spec.validators)
    {
        auto vd = PluginRegistry::instance().create_validator(v.name);
        if (!vd)
        {
            result.errors.emplace_back(
                ConfigError{Errc::Other, std::string("unknown validator: ") + v.name, {}});
            continue;
        }
        vd->validate(root_view, v.options, result.errors);
    }

    // sinks 阶段（在不修改 root 的前提下进行结果输出）
    for (const auto & s : spec.sinks)
    {
        auto sk = PluginRegistry::instance().create_sink(s.name);
        if (!sk)
        {
            result.errors.emplace_back(
                ConfigError{Errc::Other, std::string("unknown sink: ") + s.name, {}});
            continue;
        }
        bool ok = sk->write(result.root, s.options, stage_errors);
        // 合并输出阶段的错误
        if (!stage_errors.empty())
        {
            std::move(stage_errors.begin(), stage_errors.end(), std::back_inserter(result.errors));
            stage_errors.clear();
        }
        (void)ok;
    }

    return result;
}

/// plugin::PluginOptionsChecker 实现
namespace plugin
{

/**
 * @brief 构造选项检查器。
 * @param plugin_name 插件名称，用于错误与帮助文本。
 * @param options 选项键值对。
 */
PluginOptionsChecker::PluginOptionsChecker(std::string plugin_name, const PluginOptions & options)
    : _plugin_name(std::move(plugin_name)), _options(options)
{
}

/**
 * @brief 添加一条选项规格。
 * @param spec 规格定义，含名称、是否必需、枚举取值等。
 */
void
PluginOptionsChecker::add_spec(PluginOptionSpec spec)
{
    _specs.push_back(std::move(spec));
}

/**
 * @brief 校验当前选项是否满足已添加的规格。
 * @param out_errors 输出错误集合；若检出问题将追加。
 * @return 全部通过返回 true，否则返回 false。
 */
bool
PluginOptionsChecker::validate(std::vector<ConfigError> & out_errors) const
{
    bool ok = true;
    for (const auto & s : _specs)
    {
        auto it = _options.find(s.name);
        if (s.required && it == _options.end())
        {
            ok = false;
            ConfigError e{Errc::Other, _plugin_name + ": missing option '" + s.name + "'", {}};
            e.notes = std::string("plugin option required");
            out_errors.emplace_back(std::move(e));
            continue;
        }
        if (!s.enum_values.empty() && it != _options.end())
        {
            const std::string & v = it->second;
            bool hit =
                std::find(s.enum_values.begin(), s.enum_values.end(), v) != s.enum_values.end();
            if (!hit)
            {
                ok = false;
                ConfigError e{
                    Errc::Other, _plugin_name + ": invalid value for option '" + s.name + "'", {}};
                std::string evs;
                for (std::size_t i = 0; i < s.enum_values.size(); ++i)
                {
                    evs += s.enum_values[i];
                    if (i + 1 < s.enum_values.size())
                        evs += ", ";
                }
                e.notes = std::string("allowed values: [") + evs + "]";
                out_errors.emplace_back(std::move(e));
            }
        }
    }
    return ok;
}

/**
 * @brief 构建人类可读的帮助文本。
 * @return 多行字符串，描述每个选项的要求与默认值。
 */
std::string
PluginOptionsChecker::build_help_text() const
{
    std::string s;
    s += _plugin_name + " options:\n";
    for (const auto & spec : _specs)
    {
        s += "  - " + spec.name + ": ";
        s += (spec.required ? "required" : "optional");
        if (spec.default_value)
            s += std::string{", default="} + *spec.default_value;
        if (!spec.enum_values.empty())
        {
            s += ", one of {";
            for (std::size_t i = 0; i < spec.enum_values.size(); ++i)
            {
                s += spec.enum_values[i];
                if (i + 1 < spec.enum_values.size())
                    s += ", ";
            }
            s += "}";
        }
        if (!spec.description.empty())
            s += std::string{"\n      desc: "} + spec.description;
        s += "\n";
    }
    return s;
}

/**
 * @brief 获取字符串选项值。
 * @param key 选项键。
 * @param default_value 可选默认值；未提供且缺失时报错。
 * @return 成功返回值；失败返回 `unexpected(ConfigError)`。
 */
expected<std::string, ConfigError>
PluginOptionsChecker::get_string(const std::string & key,
                                 std::optional<std::string> default_value) const
{
    auto it = _options.find(key);
    if (it != _options.end())
        return it->second;
    if (default_value)
        return *default_value;
    ConfigError e{Errc::Other, _plugin_name + ": missing option '" + key + "'", {}};
    e.notes = std::string("plugin option required");
    return unexpected(std::move(e));
}

/**
 * @brief 获取整数选项值（int64）。
 * @param key 选项键。
 * @param default_value 可选默认值；未提供且缺失时报错。
 * @return 成功返回值；失败返回 `unexpected(ConfigError)`。
 */
expected<int64_t, ConfigError>
PluginOptionsChecker::get_int64(const std::string & key, std::optional<int64_t> default_value) const
{
    auto it = _options.find(key);
    if (it == _options.end())
    {
        if (default_value)
            return *default_value;
        ConfigError e{Errc::Other, _plugin_name + ": missing option '" + key + "'", {}};
        e.notes = std::string("plugin option required");
        return unexpected(std::move(e));
    }
    try
    {
        long long v = std::stoll(it->second);
        return static_cast<int64_t>(v);
    }
    catch (...)
    {
        ConfigError e{Errc::Other, _plugin_name + ": invalid integer for option '" + key + "'", {}};
        return unexpected(std::move(e));
    }
}

/**
 * @brief 获取浮点选项值（double）。
 * @param key 选项键。
 * @param default_value 可选默认值；未提供且缺失时报错。
 * @return 成功返回值；失败返回 `unexpected(ConfigError)`。
 */
expected<double, ConfigError>
PluginOptionsChecker::get_double(const std::string & key, std::optional<double> default_value) const
{
    auto it = _options.find(key);
    if (it == _options.end())
    {
        if (default_value)
            return *default_value;
        ConfigError e{Errc::Other, _plugin_name + ": missing option '" + key + "'", {}};
        e.notes = std::string("plugin option required");
        return unexpected(std::move(e));
    }
    try
    {
        double v = std::stod(it->second);
        return v;
    }
    catch (...)
    {
        ConfigError e{Errc::Other, _plugin_name + ": invalid number for option '" + key + "'", {}};
        return unexpected(std::move(e));
    }
}

/**
 * @brief 获取布尔选项值。
 * @param key 选项键。
 * @param default_value 可选默认值；未提供且缺失时报错。
 * @return 成功返回值；失败返回 `unexpected(ConfigError)`。
 */
expected<bool, ConfigError>
PluginOptionsChecker::get_bool(const std::string & key, std::optional<bool> default_value) const
{
    auto it = _options.find(key);
    if (it == _options.end())
    {
        if (default_value)
            return *default_value;
        ConfigError e{Errc::Other, _plugin_name + ": missing option '" + key + "'", {}};
        e.notes = std::string("plugin option required");
        return unexpected(std::move(e));
    }
    std::string v = it->second;
    std::transform(v.begin(),
                   v.end(),
                   v.begin(),
                   [](char c)
                   { return static_cast<char>(std::tolower(static_cast<unsigned char>(c))); });
    if (v == "true" || v == "1")
        return true;
    if (v == "false" || v == "0")
        return false;
    ConfigError e{Errc::Other, _plugin_name + ": invalid boolean for option '" + key + "'", {}};
    return unexpected(std::move(e));
}

} // namespace plugin

} // namespace cfg